///////////////////////////////////////////////////////////
// 
//  Note.cpp
//
//  Wiicussion
//  HCI 575 Class project
//  Spring 2007
// 
//  Authors:  Jeremy Bennett
//            Adam Faeth
//            Michael Oren
//
///////////////////////////////////////////////////////////


// Local Includes
#include "stdafx.h"
#include "Note.h"
#include "MyImage.h"
#include "MyContext.h"

// SDL Includes
#include <SDL_opengl.h>

// System Includes
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>

bool Note::s_bVerbose = false;

Note::Note( float fStX, float fStY, float fDistX, float fDistY, 
            float w, float h, unsigned int uiInst, unsigned int uiTime )
: _uID(),
_uiTime(uiTime),
_uiInst(uiInst),
_bMatched(false),
_fRenderSize(),
_fRenderPos(),
_fColor(),
_fStX(fStX),
_fStY(fStY),
_fDistX(fDistX),
_fDistY(fDistY),
_uiTravelTicks(1) // 0 may result in division by zero!
{
    _fRenderPos[0] = fStX;
    _fRenderPos[1] = fStY;
    _fRenderSize[0] = w;
    _fRenderSize[1] = h;
    
    _fColor[0] = 0.0f;
    _fColor[1] = 0.0f;
    _fColor[2] = 1.0f;
    _fColor[3] = 1.0f;
    
//    std::cout << "Note: @(" << fStX << "," << fStY << ") going (" 
//              << fDistX << "," << fDistY << ")" << std::endl;
}

Note::~Note()
{
}

bool 
Note::setRendPosition( const float *pPos )
{
    _fRenderPos[0] = pPos[0];
    _fRenderPos[1] = pPos[1];
    return true;
}

// Updates the position of the note
// based on time
bool
Note::postFrame(unsigned int uiTime)
{
    bool bRes = true;
    // position is a ratio of start to stop time
    float fSlope = (float(uiTime)-float(_uiTime))/float(_uiTravelTicks);
    _fRenderPos[0] = (_fDistX * fSlope) + _fStX;
    _fRenderPos[1] = (_fDistY * fSlope) + _fStY;
//    std::cout << "Note (" << _fRenderPos[0] << "x" << _fRenderPos[1] << ")" <<std::endl;

    // return false if the note is offscreen
    if(fSlope > 1.0f)
        bRes = false;
        
    return bRes;
}


// marks the note as played
bool
Note::setMatched(bool bMatch)
{
    _bMatched = bMatch;
    return true;
}

bool 
Note::setTime(unsigned int uiTime, unsigned int uiTravelTime) 
{ 
    _uiTime = uiTime; 
    _uiTravelTicks = uiTravelTime + 1; // guard against div/0
    return true;
}



// Render the note
bool 
Note::renderNote( MyContext *pContext )
{
    if ( pContext == NULL )
        return true;

    glPushMatrix();
    glLoadIdentity();
    
    glTranslatef(_fRenderPos[0],_fRenderPos[1],0.0f);
     
   // std::cout << "Note (" << _fRenderPos[0] << "x" << _fRenderPos[1] << ")" <<std::endl;
    
    float sf_bgColor[]  = { 0.3f, 0.8f, 0.3f };
    float sf_bgColorMatch[]  = { 0.3f, 0.3f, 0.8f };
    
    // Determine which texture to load (if the note was played)
    MyImage * image =  _bMatched ? (MyImage*)pContext->texture(GAME_NOTE_PLAYED) : 
                                  (MyImage*)pContext->instrument(_uiInst);
        
    image->bindTexture();
    image->enableTexture();
    
    // Render Menu
    // Color the note blue if matched, green if unmatched
    _bMatched ? glColor3fv(sf_bgColorMatch) : glColor3fv(sf_bgColor);
    
    glBegin(GL_TRIANGLE_STRIP);
    // Vertex 0
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(0.0f,0.0f,0.0f);
    // Vertex 1
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(0.0f,_fRenderSize[1],0.0f);
    // Vertex 2
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(_fRenderSize[0],0.0f,0.0f);
    // Vertex 3
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(_fRenderSize[0],_fRenderSize[1],0.0f);
    glEnd();
    
    image->disableTexture();
    
    glPopMatrix();
    return true;
}

